package com.spzx.service.impl;

import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.spzx.cart.api.domain.CartInfo;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.security.utils.SkuCacheKeyUtils;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.SkuPrice;
import com.spzx.service.ICartService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * ClassName: CartServiceImpl
 * Package: com.spzx.service.impl
 * Description:
 */
@Service
public class CartServiceImpl implements ICartService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RemoteProductService remoteProductService;

    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        Long userId = SecurityContextHolder.getUserId();
        String cacheKey = SkuCacheKeyUtils.getCacheKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cacheKey);
        Integer threshold = 99;
        String hashKey = skuId.toString();
        if (hashOps.hasKey(hashKey)) {
            //缓存中有,对数量进行累加 ，不能超过指定上限99
            CartInfo cartInfo = hashOps.get(hashKey);
            Integer totalNum = cartInfo.getSkuNum() + skuNum;
            cartInfo.setSkuNum(totalNum > threshold ? threshold : totalNum);
            cartInfo.setUpdateTime(new Date());
            hashOps.put(hashKey, cartInfo);
        } else {
            //缓存中没有则添加
            //判断购物车商品种类（不同SKU）总数大于50件
            Long count = hashOps.size();
            if (++count > 50) {
                throw new ServiceException("商品种类数量超过上限");
            }
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);
            cartInfo.setSkuNum(skuNum > threshold ? threshold : skuNum);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
            R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (R.FAIL == productSkuResult.getCode()) {
                throw new ServiceException(productSkuResult.getMsg());
            }
            ProductSku productSku = productSkuResult.getData();
            cartInfo.setCartPrice(productSku.getSalePrice());
//            cartInfo.setSkuPrice(productSku.getSalePrice());
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());

            hashOps.put(hashKey, cartInfo);

        }


    }

    @Override
    public List<CartInfo> getCartList(Long userId) {
        String cacheKey = SkuCacheKeyUtils.getCacheKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cacheKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            //购物车有商品,根据商品的skuId查询商品的实时价格
            List<Long> skuIdList = cartInfoList.stream().map(CartInfo::getSkuId).collect(Collectors.toList());
            R<List<SkuPrice>> skuPriceListResult = remoteProductService.getSkuPriceList(skuIdList,SecurityConstants.INNER);
            if (R.FAIL == skuPriceListResult.getCode()) {
                throw new ServiceException(skuPriceListResult.getMsg());
            }

            Map<Long, BigDecimal> skuPrice = skuPriceListResult.getData().stream().collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));

            cartInfoList.forEach(item -> {
                item.setSkuPrice(skuPrice.get(item.getSkuId()));

            });
            //todo:根据updateTime进行排序
            cartInfoList.sort((item1, item2) -> item2.getUpdateTime().compareTo(item1.getUpdateTime()));
            return cartInfoList;
        }
        return new ArrayList<>();
    }

    @Override
    public Integer deleteCart(List<Long> skuIds, Long userId) {
        String cacheKey = SkuCacheKeyUtils.getCacheKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cacheKey);
        for (Long skuId : skuIds) {
            hashOps.delete(skuId.toString());

        }
        return 1;
    }

    @Override
    public int changeChecked(Long skuId, Integer isChecked, Long userId) {
        String cacheKey = SkuCacheKeyUtils.getCacheKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cacheKey);
        CartInfo cartInfo = hashOps.get(skuId.toString());
        cartInfo.setIsChecked(isChecked);
        hashOps.put(skuId.toString(), cartInfo);
        return 1;
    }

    @Override
    public int allCheckCart(Integer isChecked, Long userId) {
        String cacheKey = SkuCacheKeyUtils.getCacheKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cacheKey);
        List<CartInfo> cartInfoList = hashOps.values();
        cartInfoList.forEach(cartInfo ->{
            cartInfo.setIsChecked(isChecked);
            hashOps.put(cartInfo.getSkuId().toString(), cartInfo);
        });
        return 1;
    }

    @Override
    public Boolean clearCart(Long userId) {
        String cacheKey = SkuCacheKeyUtils.getCacheKey(userId);
        return redisTemplate.delete(cacheKey);

    }

    @Override
    public void updateCartPrice(Long userId) {
        //获取购物车中所有的skuId
        String cacheKey = SkuCacheKeyUtils.getCacheKey(userId);
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cacheKey);
        List<Long> skuIdList = hashOps.keys().stream().map(key -> Long.parseLong(key)).collect(Collectors.toList());

        //查询数据最新的价格
        R<List<SkuPrice>> skuPriceListResult = remoteProductService.getSkuPriceList(skuIdList, SecurityConstants.INNER);
        if (R.FAIL == skuPriceListResult.getCode()){
            throw new ServiceException(skuPriceListResult.getMsg());
        }
        Map<Long, BigDecimal> skuPriceMap = skuPriceListResult.getData().stream()
                .collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));

        //更新购物车价格
        hashOps.values().forEach(cartInfo->{
            cartInfo.setSkuPrice(skuPriceMap.get(cartInfo.getSkuId()));
            hashOps.put(cartInfo.getSkuId().toString(), cartInfo);
        });

    }

    @Override
    public List<CartInfo> getCheckList(Long userId) {

        List<CartInfo> checkList = new ArrayList<>();
        String cacheKey = SkuCacheKeyUtils.getCacheKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cacheKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            for (CartInfo cartInfo : cartInfoList) {
                if (cartInfo.getIsChecked() == 1){
                    checkList.add(cartInfo);
                }
            }
        }
        return checkList;
    }


}
